﻿using Simple.ISysRepository;
using Simple.Tools.Security;
using Simple.Tools.SnowFlake;
using Simple.Tools.Verify;
using Simple.Tools;
using SimpleSaas.Common;
using SimpleSaas.Common.DataBase;
using SimpleSaas.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using SimpleSaas.Entity.Entity;
using SimpleSaas.Common.Execption;

namespace Simple.SysRepository
/// <summary>
/// 版 本 钢易智企2.0 V 2.0.0 钢易智企2.0
/// Copyright (c) 2023 杭州钢易科技有限公司
/// 创建人：曾东明
/// 日 期：2024
/// 描 述：
/// </summary>
{
	public class SysUserRepository : WholeRepository<SysUserEntity, long>, ISysUserRepository
	{
		public SysUserRepository() { }
		/// <summary>
		/// 
		/// </summary>
		[Autowired]
		private ISimpleMapper simpleMapper { get; set; }

		/// <summary>
		/// 
		/// </summary>
		[Autowired]
		protected ISysUserMenuRepository sysUserMenuRepository { get; set; }

		[Autowired]
		protected ISysUserDeptRepository sysUserDeptRepository { get; set; }

		/// <summary>
		///  添加用户
		/// </summary>
		/// <param name="userDto"></param>
		public async Task AddAsync(SysUserDto userDto)
		{
			var reuslt = userDto.Verify();
			if (!reuslt.Item2)
			{
				throw new BusinessException(reuslt.Item1);
			}

			if (await AnyAsync(user => !user.IsDeleted && user.PhoneNumber.Equals(userDto.PhoneNumber)))
			{
				throw new BusinessException("电话号码已经存在!");
			}
			SysUserEntity sysUser = new SysUserEntity();

			simpleMapper.Map(userDto, sysUser);

			sysUser.Account = await GetAccount();

			sysUser.Id = Worker.GetId();

			sysUser.PasswordSalt = 20.Random();

			sysUser.PasswordHash = Security.AesEncrypt(userDto.Password, sysUser.PasswordSalt);

			#region 初始化菜单

			List<SysUserMenuRelationEntity> sysMenuList = new List<SysUserMenuRelationEntity>();

			if (SimpleCheck.IsNotNullOrEmpty(userDto.SysMenuList))
			{
				foreach (var item in userDto.SysMenuList)
				{
					SysUserMenuRelationEntity userMenu = new SysUserMenuRelationEntity();
					userMenu.UserId = sysUser.Id;
					userMenu.MenuId = item.Id.ToInt64();
					userMenu.AppId = item.AppId.ToInt64();
					sysMenuList.Add(userMenu);
				}
			}
			#endregion

			#region 添加部门
			List<SysUserDeptRelationEntity> sysDeptList = new List<SysUserDeptRelationEntity>();

			if (SimpleCheck.IsNotNullOrEmpty(userDto.SysDeptList))
			{
				foreach (var item in userDto.SysDeptList)
				{
					SysUserDeptRelationEntity userDept = new SysUserDeptRelationEntity();
					userDept.UserId = sysUser.Id;
					userDept.DeptId = item.Id.ToInt64();
					sysDeptList.Add(userDept);
				}
			}
			#endregion
			await CreateAsync(sysUser);

			await sysUserDeptRepository.CreateAsync(sysDeptList);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public async Task<string> GetAccount()
		{
			string result;
			while (true)
			{
				string account = 10.Random();
				if (!await AnyAsync(sysUser => sysUser.Account.Equals(account)))
				{
					result = account;
					break;
				}
			}
			return result;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="matchCondition"></param>
		/// <returns></returns>
		public ISugarQueryable<LoginUserInfo> Query(Action<ISugarQueryable<SysUserEntity, SysTenantEntity>> matchCondition)
		{
			var query = dbClient.Queryable<SysUserEntity, SysTenantEntity>
				((user, tenant) => new JoinQueryInfos(
					JoinType.Left, user.TenantId == tenant.Id));
			SimpleCheck.IsNullThrowException(matchCondition);

			matchCondition.Invoke(query);

			return query.Select((user, tenant) =>
				new LoginUserInfo()
				{
					UserId = user.Id,
					UserName = user.UserName,
					DatabaseId = tenant.DatabaseId,
					PhoneNumber = user.PhoneNumber,
					TenantName = tenant.TenantName,
					TenantId = tenant.Id,
					Apps = SqlFunc.Subqueryable<SysAppEntity>()
					.Where((app) => SqlFunc.Subqueryable<SysAppTenantRelationEntity>()
					.Where(relation => relation.TenantId.Equals(tenant.Id))
					.ToList((relation) => relation.AppId).Contains(app.Id))
					.ToList((app) => new SysAppView()
					{
						AppName = app.AppName,
						Remark = app.Remark,
						Sort = app.Sort,
					})
				});
		}
	}
}
